﻿using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using gtasks.Auth;
using gtasks.Model;
using gtasks.Model.Convert;
using pub.GUI.Dialog;
using pub.NET20Fix;
using pub.Types;
using todo;
using todo.Model;
using todo.Persistence;

namespace gtasks
{
    internal partial class GTasksForm : Form
    {
        public TaskLists Lists;
        private int _loadingCounter;

        public GTasksForm()
        {
            InitializeComponent();
            this.Font = SystemFonts.DialogFont;
#if zh
            this.Text = "Google 任务";
            this.lblTaskLists.Text = "任务列表";
            this.lnkDisconnect.Text = "断开";
            btnOpen.Text = "打开(&O)";
            btnClose.Text = "关闭(&C)";
            btnNew.Text = "新建(&N)";
            btnDelete.Text = "删除(&D)";
#endif
        }

        private void GTasksForm_Load(object sender, EventArgs e)
        {
            panelLoading.Dock = DockStyle.Fill;
            AuthManager.Instance.OnException += OnAsyncException;
            TaskListManager.Instance.OnException += OnAsyncException;
        }

        void OnAsyncException(Exception e)
        {
            App.OnUnknownException(e);
            if(panelLoading.Visible)
            {
                this.Close();
            }
        }

        private void FillList(TaskLists lists)
        {
            Lists = lists;
            lvTaskLists.Items.Clear();
            foreach (var taskList in Lists.items)
            {
                lvTaskLists.Items.Add(taskList.title);
            }
            UpdateColumnWidth();
            panelLoading.Visible = false;
            timerLoading.Enabled = false;
            panelMain.Visible = true;
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void GTasksForm_Resize(object sender, EventArgs e)
        {
            UpdateColumnWidth();
        }

        private void UpdateColumnWidth()
        {
            lvTaskLists.Columns[0].Width = lvTaskLists.ClientSize.Width - 2;
        }

        private void GTasksForm_Shown(object sender, EventArgs e)
        {
            LoadList();
        }

        private void LoadList()
        {
            try
            {
                lvTaskLists.Items.Clear();
                var loadingMsg = "Loading...";
#if zh
                loadingMsg = "加载中...";
#endif
                lvTaskLists.Items.Add(loadingMsg);
                lvTaskLists.Enabled = false;
                TaskListManager.Instance.List(lists =>
                {
                    FillList(lists);
                    lvTaskLists.Enabled = true;
                });
            }
            catch (AbortException ex)
            {
                this.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                this.Close();
            }
        }

        private void lnkDisconnect_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            AuthManager.Instance.Disconnect();
            this.Close();
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            var taskList = GetSelectedTaskList();
            if(taskList == null)
            {
                return;
            }

            var text = "Opening...";
#if zh
            text = "正打开...";
#endif
            btnOpen.Text = text;
            btnOpen.Enabled = false;
            
            Open(taskList);
        }

        private void Open(TaskList taskList)
        {
            var id = taskList.id;
            
            var path = Path.Combine(App.DataPath, "gtasks");
            var dir = new DirectoryInfo(path);
            var files = dir.Exists? dir.GetFiles("*.todolist"): new FileInfo[0];
            
            string localFile = null;
            foreach (var file in files)
            {
                var todoList = TodoListParser.Parse(file.FullName);
                if(todoList != null && todoList.Id == id)
                {
                    if(todoList.UpdateTime == taskList.updated)
                    {
                        localFile = file.FullName;
                        break;
                    }
                }
            }
            if(localFile != null)
            {
                //direct open
                //MessageBox.Show("open " + localFile);
                App.MainForm.OnOpen(localFile);
                this.Close();
            }
            else
            {
                Download(taskList);
            }
        }

        private void Download(TaskList taskList)
        {
            var path = Path.Combine(App.DataPath, "gtasks");
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            var localFile = Path.Combine(path, "(google tasks)" + taskList.title + ".todolist");
            TaskManager.Instance.LoadTasks(taskList.id, tasks => {
                var todolist = TaskListToTodoList.Convert(taskList, tasks);
                TodoListWriter.Save(todolist, localFile);
                Dispatcher.Current.Invoke(() => {
                    //open
                    App.MainForm.OnOpen(localFile);
                    this.Close();
                });
            });
        }

        private void timerLoading_Tick(object sender, EventArgs e)
        {
            var text = "Loading tasklists";
#if zh
            text = "正在加载任务列表";
#endif
            text += new string('.', (++_loadingCounter % 3) + 1);
            lblLoading.Text = text;
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            var msg = "Please input tasklist title:";
            var dlgTitle = "New Tasklist";
#if zh
            msg = "请输入任务列表的标题：";
            dlgTitle = "新建任务列表";
#endif
            var title = InputBox.Show(msg, dlgTitle);
            if(!string.IsNullOrEmpty(title))
            {
                var text = "Creating...";
#if zh
                text = "创建中...";
#endif
                btnNew.Text = text;
                btnNew.Enabled = false;
                TaskListManager.Instance.New(title, list => {
                    text = "&New";
#if zh
                    text = "新建(&N)";
#endif
                    btnNew.Text = text;
                    btnNew.Enabled = true;
                    LoadList();
                });
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            var taskList = GetSelectedTaskList();
            if(taskList != null)
            {
                var text = "Deleting...";
#if zh
                text = "删除中...";
#endif
                btnDelete.Text = text;
                btnDelete.Enabled = false;
                TaskListManager.Instance.Delete(taskList.id, () => {
                    text = "&Delete";
#if zh
                    text = "删除(&D)";
#endif
                    btnDelete.Text = text;
                    btnDelete.Enabled = true;
                    LoadList();
                });
            }
        }

        private TaskList GetSelectedTaskList()
        {
            if (lvTaskLists.SelectedIndices.Count == 0)
            {
                var msg = "Please select a tasklist";
                var title = "Prompt";
#if zh
                msg = "请选择一个任务列表";
                title = "提示";
#endif
                MessageBox.Show(msg, title);
                return null;
            }
            var taskList = Lists.items[lvTaskLists.SelectedIndices[0]];
            return taskList;
        }

        private void GTasksForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            TaskListManager.Instance.OnException -= OnAsyncException;
            AuthManager.Instance.OnException -= OnAsyncException; 
            TaskListManager.Instance.AbortProcessing();
            TaskManager.Instance.AbortProcessing();
        }

    }
}